<template>
  <div class="message-list" ref="messageListRef">
    <div v-for="(message, index) in messages"
         :key="index"
         :class="['message-item', message.role]">
      <div class="message-inner">
        <div class="avatar">
          <!-- AI头像 SVG -->
          <svg v-if="message.role === 'assistant'" viewBox="0 0 24 24" class="avatar-svg">
            <path fill="currentColor" d="M21 11.18V9.72c0-.47-.16-.92-.46-1.28L16.6 3.72c-.38-.46-.94-.72-1.54-.72H8.94c-.6 0-1.16.26-1.54.72L3.46 8.44c-.3.36-.46.81-.46 1.28v1.46c0 .68.37 1.31.97 1.63l3.25 1.76c-.03.12-.04.24-.04.36V17c0 1.1.9 2 2 2h4.2c1.1 0 2-.9 2-2v-2.07c0-.12-.01-.24-.04-.36l3.25-1.76c.6-.32.97-.95.97-1.63zM12 17.5c-2.48 0-4.5-2.02-4.5-4.5S9.52 8.5 12 8.5s4.5 2.02 4.5 4.5-2.02 4.5-4.5 4.5z"/>
          </svg>
          <!-- 用户头像 SVG -->
          <svg v-else viewBox="0 0 24 24" class="avatar-svg">
            <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/>
          </svg>
        </div>
        <div class="message-content">
          <div class="message-header">
            <span class="message-time">{{ formatTime(message.timestamp) }}</span>
            <div class="message-actions" v-if="message.role === 'assistant'">
              <button class="action-button" @click="$emit('regenerate', index)">
                <svg viewBox="0 0 24 24" class="action-icon" width="16" height="16">
                  <path fill="currentColor" d="M17.65 6.35A7.958 7.958 0 0 0 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/>
                </svg>
                重新回复
              </button>
              <button class="action-button" @click="copyMessage(message.content)">
                <svg viewBox="0 0 24 24" class="action-icon" width="16" height="16">
                  <path fill="currentColor" d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/>
                </svg>
                复制内容
              </button>
            </div>
          </div>
          <div v-if="message.role === 'user'" class="message-text">{{ message.content }}</div>
          <div v-else class="message-text markdown-body" v-html="renderMarkdown(message.content)"></div>

          <!-- AI回复的元信息 -->
          <div v-if="message.role === 'assistant'" class="message-meta">
            <div class="meta-info">
              <span class="token-count" :class="{ 'token-limit': message.tokens > maxOutputTokens }">
                <svg class="meta-icon" viewBox="0 0 24 24" width="14" height="14">
                  <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10s10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8s8 3.59 8 8s-3.59 8-8 8zm-1-4h2v2h-2v-2zm0-2h2V7h-2v7z"/>
                </svg>
                {{ formatTokenCount(message.tokens || 0) }} tokens
              </span>
              <span class="response-time" v-if="message.responseTime && message.responseTime > 0">
                <svg class="meta-icon" viewBox="0 0 24 24" width="14" height="14">
                  <path fill="currentColor" d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8s8 3.58 8 8s-3.58 8-8 8zm.5-13H11v6l5.25 3.15l.75-1.23l-4.5-2.67z"/>
                </svg>
                {{ formatResponseTime(message.responseTime) }}
              </span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { marked } from 'marked'
import hljs from 'highlight.js'

const props = defineProps({
  messages: {
    type: Array,
    required: true
  },
  maxOutputTokens: {
    type: Number,
    default: 8000
  }
})

const emit = defineEmits(['regenerate', 'scroll'])

const messageListRef = ref(null)

// 格式化时间
const formatTime = (timestamp) => {
  if (!timestamp) return ''
  const date = new Date(timestamp)
  return date.toLocaleTimeString('zh-CN', {
    hour: '2-digit',
    minute: '2-digit',
    hour12: false
  })
}

// 复制消息内容
const copyMessage = (content) => {
  navigator.clipboard.writeText(content).then(() => {
    console.log('内容已复制')
  }).catch(err => {
    console.error('复制失败:', err)
  })
}

// 渲染Markdown
const renderMarkdown = (content) => {
  try {
    return marked(content)
  } catch (e) {
    console.error('Markdown rendering error:', e)
    return content
  }
}

// 格式化token数量
const formatTokenCount = (count) => {
  return new Intl.NumberFormat('zh-CN').format(count)
}

// 格式化响应时间
const formatResponseTime = (ms) => {
  if (!ms || ms <= 0) return ''
  if (ms < 1000) {
    return `${ms}ms`
  } else {
    return `${(ms / 1000).toFixed(1)}s`
  }
}

// 检查滚动位置
const checkScroll = () => {
  if (!messageListRef.value) return

  const { scrollTop, scrollHeight, clientHeight } = messageListRef.value
  const distanceFromBottom = scrollHeight - scrollTop - clientHeight

  emit('scroll', distanceFromBottom > 100)
}

// 添加滚动到底部的方法
const scrollToBottom = () => {
  if (!messageListRef.value) return

  messageListRef.value.scrollTo({
    top: messageListRef.value.scrollHeight,
    behavior: 'smooth'
  })
}

// 暴露方法给父组件
defineExpose({
  scrollToBottom
})

onMounted(() => {
  if (messageListRef.value) {
    messageListRef.value.addEventListener('scroll', checkScroll)
  }
})

onUnmounted(() => {
  if (messageListRef.value) {
    messageListRef.value.removeEventListener('scroll', checkScroll)
  }
})
</script>

<style scoped>
.message-list {
  flex: 1;
  overflow-y: auto;
  padding: 0 10%;
  scroll-behavior: smooth;
}

.message-item {
  padding: 24px 0;
  transition: all 0.3s ease;
  animation: message-fade-in 0.3s ease;
}

.message-item.assistant {
  background-color: #f7f7f8;
}

@media (prefers-color-scheme: dark) {
  .message-item.assistant {
    background-color: transparent;
  }

}

.message-inner {
  max-width: 48rem;
  margin: 0 auto;
  display: flex;
  gap: 24px;
  padding: 0 24px;
  animation: message-slide-in 0.3s ease;
}

.avatar {
  width: 36px;
  height: 36px;
  border-radius: 6px;
  overflow: hidden;
  flex-shrink: 0;
  background-color: #10a37f;
  padding: 6px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease;
}

.avatar:hover {
  transform: scale(1.05);
}

.avatar-svg {
  width: 100%;
  height: 100%;
  color: #ffffff;
}

.message-item.user .avatar {
  background-color: #1a7fdb;
}

.message-content {
  flex: 1;
  padding: 8px 12px;
  background-color: #ffffff;
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.message-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-size: 12px;
}

.message-time {
  color: #6b7280;
}

.message-actions {
  display: flex;
  gap: 8px;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.message-item:hover .message-actions {
  opacity: 1;
}

.action-button {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  font-size: 12px;
  color: #6b7280;
  background-color: transparent;
  border: 1px solid #e5e7eb;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.action-button:hover {
  background-color: #f3f4f6;
  border-color: #d1d5db;
  color: #374151;
}

.action-icon {
  width: 16px;
  height: 16px;
}

.message-text {
  font-size: 15px;
  line-height: 1.6;
  color: #374151;
  white-space: pre-wrap;
  word-wrap: break-word;
  padding: 8px 12px;
}

.message-meta {
  display: flex;
  justify-content: flex-end;
  margin-top: 8px;
  font-size: 12px;
}

.meta-info {
  display: flex;
  gap: 12px;
  padding: 4px 8px;
  background-color: #f8fafc;
  border-radius: 6px;
  border: 1px solid #e2e8f0;
}

.token-count,
.response-time {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: #64748b;
}

.meta-icon {
  opacity: 0.7;
}

.token-count.token-limit {
  color: #ef4444;
}

.meta-info:hover {
  background-color: #f1f5f9;
  border-color: #cbd5e1;
}

@keyframes message-fade-in {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes message-slide-in {
  from {
    opacity: 0;
    transform: translateX(-20px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

/* Markdown 样式优化 */
:deep(.markdown-body) {
  font-size: 15px;
  line-height: 1.6;
  color: #1f2937;
}

:deep(.markdown-body p) {
  margin: 8px 0;
}

:deep(.markdown-body h1),
:deep(.markdown-body h2),
:deep(.markdown-body h3),
:deep(.markdown-body h4),
:deep(.markdown-body h5),
:deep(.markdown-body h6) {
  margin-top: 16px;
  margin-bottom: 8px;
  line-height: 1.4;
}

:deep(.markdown-body ul),
:deep(.markdown-body ol) {
  margin-top: 4px;
  margin-bottom: 4px;
  padding-left: 1.5em;
}

:deep(.markdown-body li) {
  margin: 2px 0;
}

:deep(.markdown-body li > p) {
  margin: 4px 0;
}

:deep(.markdown-body pre) {
  margin: 8px 0;
  padding: 12px;
}

:deep(.markdown-body table) {
  margin: 8px 0;
}

:deep(.markdown-body blockquote) {
  margin: 8px 0;
  padding: 4px 12px;
  color: #4b5563;
  border-left: 4px solid #e5e7eb;
}

:deep(.markdown-body hr) {
  margin: 12px 0;
}

/* 代码块样式 */
:deep(.code-block) {
  position: relative;
  background-color: #1e1e1e;
  border-radius: 8px;
  margin: 16px 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}

:deep(.code-header) {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 16px;
  background-color: #2d2d2d;
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
  border-bottom: 1px solid #3d3d3d;
}

:deep(.code-lang) {
  font-size: 12px;
  color: #ccc;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}

:deep(.copy-button) {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  font-size: 12px;
  color: #ccc;
  background-color: transparent;
  border: 1px solid #4d4d4d;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
}

:deep(.copy-button:hover) {
  background-color: #3d3d3d;
  border-color: #6d6d6d;
}

:deep(.copy-button.copied) {
  background-color: #2ea043;
  border-color: #2ea043;
  color: white;
}

/* 暗色主题适配 */
@media (prefers-color-scheme: dark) {
  .message-content {
    background-color: #2d2d2d;
    color: #e5e7eb;
  }

  .message-text {
    color: #e5e7eb;
  }

  .meta-info {
    background-color: #374151;
    border-color: #4b5563;
  }

  :deep(.markdown-body) {
    color: #e2e8f0;
  }

  :deep(.markdown-body blockquote) {
    color: #9ca3af;
    border-left-color: #4b5563;
  }
}
</style>
